//************************************************************************
//Developed by Guo Ming Li 2009/2010
//Source code:
//  The source code may be freely modified or used but this credit section may not be removed 
//  The original author must be notified of any modifications plus a copy of 
//  the changed source code
//Contact info: mailto://gming.li@gmail.com
//************************************************************************
using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using System.Collections.ObjectModel;
using Microsoft.BizTalk.ExplorerOM;


namespace GML.BizTalk.OperationManager.Library
{
    public class MSBTS_Orchestration
    {
        //public static bool Enlist(string OrchestrationName, string AssemblyName, string AssemblyVersion, 
        //                                            string AssemblyCulture, string AssemblyPublicKeyToken, string OverrideHostName,
        //                                            bool StartAfterEnlist, Nullable<int> AutoEnableReceiveLocationFlag, 
        //                                            Nullable<int> AutoResumeOrchestrationInstanceFlag, 
        //                                            Nullable<int> AutoStartSendPortsFlag )
        public static bool Enlist(GML.BizTalk.OperationManager.MSBTSOperations.MSBTS_Orchestration oOrchestration, ref List<GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject> outputParams, ref Exception outException)
        {
            //set up a WMI query to acquire a list of orchestrations with the given Name and 
            //AssemblyName key values.  This should be a list of zero or one Orchestrations.
            //Create the WMI search object.
            ManagementObjectSearcher Searcher = new ManagementObjectSearcher();
            // create the scope node so we can set the WMI root node correctly.
            ManagementScope Scope = null;
            string HostName = "";
            // Build a Query to enumerate the MSBTS_Orchestration instances with the
            // specified name and assembly name.
            SelectQuery Query = new SelectQuery();
            ManagementObjectCollection QueryCol = null;
            ManagementBaseObject inParams = null;
            System.Management.InvokeMethodOptions imo = null;
            ManagementNamedValueCollection nvc = null;
            ManagementBaseObject outParams = null;
            GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject mbo = null;
            PropertyDataCollection.PropertyDataEnumerator pde = null;
            QualifierDataCollection.QualifierDataEnumerator qde = null;
            try
            {
                Scope = new ManagementScope("root\\MicrosoftBizTalkServer");
                Searcher.Scope = Scope;

                Query.QueryString = "SELECT * FROM MSBTS_HostSetting WHERE IsDefault ='TRUE'";

                // Set the query for the searcher.
                Searcher.Query = Query;
                QueryCol = Searcher.Get();

                foreach (ManagementObject Inst in QueryCol)
                {
                    //Get the default host name.
                    HostName = Inst.Properties["Name"].Value.ToString();

                    System.Diagnostics.Debug.WriteLine("The default host is " + HostName + ".");
                }

                // Build a Query to enumerate the MSBTS_Orchestration instances with the
                // specified name and assembly name.
                Query.QueryString = "SELECT * FROM MSBTS_Orchestration WHERE Name = '" + oOrchestration.Properties.Name +
                                                      "' AND AssemblyName = '" + oOrchestration.Properties.AssemblyName +
                                                     "'  AND AssemblyVersion  = '" + oOrchestration.Properties.AssemblyVersion +
                                                     "'  AND AssemblyCulture  = '" + oOrchestration.Properties.AssemblyCulture +
                                                     "'  AND AssemblyPublicKeyToken   = '" + oOrchestration.Properties.AssemblyPublicKeyToken + "' ";

                // Set the query for the searcher.
                Searcher.Query = Query;
                QueryCol = Searcher.Get();

                // Use a bool to tell if we enter the for loop
                // below because Count property is not supported
                bool OrchestrationFound = false;

                foreach (ManagementObject Inst in QueryCol)
                {
                    // There is at least one Orchestration
                    OrchestrationFound = true;
                    int OrchestrationStatus = Convert.ToInt32(Inst.GetPropertyValue("OrchestrationStatus"));
                    System.Diagnostics.Debug.WriteLine("The Orchestration status is: " + OrchestrationStatus + ".");
                    Logger.doLog(Guid.NewGuid().ToString(), "The Orchestration status is: " + OrchestrationStatus + ".", Logger.ServerityLevel.INFO);
                    if (OrchestrationStatus == Convert.ToInt32(GML.BizTalk.OperationManager.Library.OrchestrationStatus.Started) ||
                        OrchestrationStatus == Convert.ToInt32(GML.BizTalk.OperationManager.Library.OrchestrationStatus.Stopped))
                    {
                        return true;
                    }

                    inParams = Inst.GetMethodParameters("Enlist");
                    //Fill in input parameter values
                    if (oOrchestration.InputParams != null && oOrchestration.InputParams.Length > 0)
                    {
                        foreach (GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject inputParam in oOrchestration.InputParams)
                        {
                            inParams[inputParam.Param] = inputParam.Value;
                        }
                    }

                    if (string.IsNullOrEmpty(oOrchestration.Properties.HostName))
                    {
                        inParams["HostName"] = HostName;
                        System.Diagnostics.Debug.WriteLine("The Orchestration will be enlisted with the host: " + HostName + ".");
                        Logger.doLog(Guid.NewGuid().ToString(), "The Orchestration will be enlisted with the host: " + HostName + ".", Logger.ServerityLevel.INFO);
                    }
                    else
                    {
                        inParams["HostName"] = oOrchestration.Properties.HostName;
                        System.Diagnostics.Debug.WriteLine("The Orchestration will be enlisted with the host: " + oOrchestration.Properties.HostName + ".");
                        Logger.doLog(Guid.NewGuid().ToString(), "The Orchestration will be enlisted with the host: " + oOrchestration.Properties.HostName + ".", Logger.ServerityLevel.INFO);
                    }

                    if (oOrchestration.InvokeMethodOptions != null)
                    {
                        nvc = new ManagementNamedValueCollection();
                        GML.BizTalk.OperationManager.MSBTSOperations.ManagementNamedValueCollection[] nvcInputs = oOrchestration.InvokeMethodOptions;
                        foreach (GML.BizTalk.OperationManager.MSBTSOperations.ManagementNamedValueCollection nvcInput in nvcInputs)
                        {
                            nvc.Add(nvcInput.Name, nvcInput.Value);
                        }
                        if (oOrchestration.TimeOut != null)
                        {
                            imo = new InvokeMethodOptions(nvc, new TimeSpan(oOrchestration.TimeOut.Day, oOrchestration.TimeOut.Hour, oOrchestration.TimeOut.Minute, oOrchestration.TimeOut.Second, oOrchestration.TimeOut.Millisecond));
                        }
                        else
                        {
                            imo = new InvokeMethodOptions(nvc, new TimeSpan(0, 15, 0));
                        }
                    }

                    outParams = Inst.InvokeMethod("Enlist", inParams, imo);
                    System.Diagnostics.Debug.WriteLine("The Orchestration [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "] was successfully enlisted.");

                    Logger.doLog(Guid.NewGuid().ToString(), "The Orchestration [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "] was successfully enlisted.", Logger.ServerityLevel.INFO);

                    mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                    if (outputParams == null) outputParams = new List<GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject>();
                    pde = outParams.Properties.GetEnumerator();
                    while (pde.MoveNext())
                    {
                        try
                        {
                            mbo.Param = pde.Current.ToString();
                            mbo.Value = outParams.GetPropertyValue(mbo.Param).ToString();

                            outputParams.Add(mbo);
                        }
                        catch (Exception)
                        {
                        }
                        mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                    }
                    pde = outParams.SystemProperties.GetEnumerator();
                    while (pde.MoveNext())
                    {
                        try
                        {
                            mbo.Param = pde.Current.ToString();
                            mbo.Value = outParams.GetPropertyValue(mbo.Param).ToString();

                            outputParams.Add(mbo);

                        }
                        catch (Exception)
                        {
                        }
                        mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                    }

                    qde = outParams.Qualifiers.GetEnumerator();
                    while (qde.MoveNext())
                    {
                        try
                        {
                            mbo.Param = qde.Current.ToString();
                            mbo.Value = outParams.GetQualifierValue(mbo.Param).ToString();

                            outputParams.Add(mbo);

                        }
                        catch (Exception e)
                        {
                            Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                            Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);
                        }
                        mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                    }
                }

                if (!OrchestrationFound)
                {
                    System.Diagnostics.Debug.WriteLine("No Orchestration found  [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "].");
                    Logger.doLog(Guid.NewGuid().ToString(), "No Orchestration found  [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "].", Logger.ServerityLevel.INFO);
                }
                return true;
            }

            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("An exception occurred " + ex.Message);
                System.Diagnostics.Debug.WriteLine(ex.StackTrace);
                Logger.doLog(Guid.NewGuid().ToString(), ex.Message, Logger.ServerityLevel.ERROR);
                Logger.doLog(Guid.NewGuid().ToString(), ex.StackTrace, Logger.ServerityLevel.ERROR);
                outException = ex;
                return false;
            }
            finally
            {
                Searcher = null;
                Scope = null;
                HostName = null;
                Query = null;
                QueryCol = null;
                inParams = null;
                imo = null;
                nvc = null;
                outParams = null;
                mbo = null;
                pde = null;
                qde = null;
            }

        }
        public static bool Start(GML.BizTalk.OperationManager.MSBTSOperations.MSBTS_Orchestration oOrchestration, ref List<GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject> outputParams, ref Exception outException)
        {
            //set up a WMI query to acquire a list of orchestrations with the given Name and 
            //AssemblyName key values.  This should be a list of zero or one Orchestrations.
            //Create the WMI search object.
            ManagementObjectSearcher Searcher = new ManagementObjectSearcher();
            // create the scope node so we can set the WMI root node correctly.
            ManagementScope Scope = null;
            //string HostName = "";
            // Build a Query to enumerate the MSBTS_Orchestration instances with the
            // specified name and assembly name.
            SelectQuery Query = new SelectQuery();
            ManagementObjectCollection QueryCol = null;
            ManagementBaseObject inParams = null;
            System.Management.InvokeMethodOptions imo = null;
            ManagementNamedValueCollection nvc = null;
            ManagementBaseObject outParams = null;
            GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject mbo = null;
            PropertyDataCollection.PropertyDataEnumerator pde = null;
            QualifierDataCollection.QualifierDataEnumerator qde = null;
            try
            {
                // create the scope node so we can set the WMI root node correctly.
                Scope = new ManagementScope("root\\MicrosoftBizTalkServer");
                Searcher.Scope = Scope;

                //string HostName = "";

                // Build a Query to enumerate the MSBTS_Orchestration instances with the
                // specified name and assembly name.
                Query = new SelectQuery();

                // Build a Query to enumerate the MSBTS_Orchestration instances with the
                // specified name and assembly name.
                Query.QueryString = "SELECT * FROM MSBTS_Orchestration WHERE Name = '" + oOrchestration.Properties.Name +
                                                      "' AND AssemblyName = '" + oOrchestration.Properties.AssemblyName +
                                                     "'  AND AssemblyVersion  = '" + oOrchestration.Properties.AssemblyVersion +
                                                     "'  AND AssemblyCulture  = '" + oOrchestration.Properties.AssemblyCulture +
                                                     "'  AND AssemblyPublicKeyToken   = '" + oOrchestration.Properties.AssemblyPublicKeyToken + "' ";

                // Set the query for the searcher.
                Searcher.Query = Query;
                QueryCol = Searcher.Get();

                // Use a bool to tell if we enter the for loop
                // below because Count property is not supported
                bool OrchestrationFound = false;

                foreach (ManagementObject Inst in QueryCol)
                {
                    // There is at least one Orchestration
                    OrchestrationFound = true;
                    int OrchestrationStatus = Convert.ToInt32(Inst.GetPropertyValue("OrchestrationStatus"));
                    System.Diagnostics.Debug.WriteLine("The Orchestration status is: " + OrchestrationStatus + ".");
                    if (OrchestrationStatus == Convert.ToInt32(GML.BizTalk.OperationManager.Library.OrchestrationStatus.Started))
                    {
                        return true;
                    }


                    inParams = Inst.GetMethodParameters("Start");
                    //Fill in input parameter values
                    if (oOrchestration.InputParams != null && oOrchestration.InputParams.Length > 0)
                    {
                        foreach (GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject inputParam in oOrchestration.InputParams)
                        {
                            inParams[inputParam.Param] = inputParam.Value;
                        }
                    }

                    imo = null;
                    if (oOrchestration.InvokeMethodOptions != null)
                    {
                        nvc = new ManagementNamedValueCollection();
                        GML.BizTalk.OperationManager.MSBTSOperations.ManagementNamedValueCollection[] nvcInputs = oOrchestration.InvokeMethodOptions;
                        foreach (GML.BizTalk.OperationManager.MSBTSOperations.ManagementNamedValueCollection nvcInput in nvcInputs)
                        {
                            nvc.Add(nvcInput.Name, nvcInput.Value);
                        }
                        if (oOrchestration.TimeOut != null)
                        {
                            imo = new InvokeMethodOptions(nvc, new TimeSpan(oOrchestration.TimeOut.Day, oOrchestration.TimeOut.Hour, oOrchestration.TimeOut.Minute, oOrchestration.TimeOut.Second, oOrchestration.TimeOut.Millisecond));
                        }
                        else
                        {
                            imo = new InvokeMethodOptions(nvc, new TimeSpan(0, 15, 0));
                        }
                    }

                    outParams = Inst.InvokeMethod("Start", inParams, imo);
                    System.Diagnostics.Debug.WriteLine("The Orchestration [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "] was successfully started.");

                    Logger.doLog(Guid.NewGuid().ToString(), "The Orchestration [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "] was successfully started.", Logger.ServerityLevel.INFO);

                    mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                    if (outputParams == null) outputParams = new List<GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject>();
                    pde = outParams.Properties.GetEnumerator();
                    while (pde.MoveNext())
                    {
                        try
                        {
                            mbo.Param = pde.Current.ToString();
                            mbo.Value = outParams.GetPropertyValue(mbo.Param).ToString();

                            outputParams.Add(mbo);
                        }
                        catch (Exception e)
                        {
                            Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                            Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);

                        }
                        mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                    }
                    pde = outParams.SystemProperties.GetEnumerator();
                    while (pde.MoveNext())
                    {
                        try
                        {
                            mbo.Param = pde.Current.ToString();
                            mbo.Value = outParams.GetPropertyValue(mbo.Param).ToString();

                            outputParams.Add(mbo);

                        }
                        catch (Exception e)
                        {
                            Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                            Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);

                        }
                        mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                    }

                    qde = outParams.Qualifiers.GetEnumerator();
                    while (qde.MoveNext())
                    {
                        try
                        {
                            mbo.Param = qde.Current.ToString();
                            mbo.Value = outParams.GetQualifierValue(mbo.Param).ToString();

                            outputParams.Add(mbo);

                        }
                        catch (Exception)
                        {
                        }
                        mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                    }
                }

                if (!OrchestrationFound)
                {
                    System.Diagnostics.Debug.WriteLine("No Orchestration found  [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "].");
                    Logger.doLog(Guid.NewGuid().ToString(), "No Orchestration found  [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "].", Logger.ServerityLevel.INFO);
                }
                return true;
            }

            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("An exception occurred " + ex.Message);
                System.Diagnostics.Debug.WriteLine(ex.StackTrace);
                Logger.doLog(Guid.NewGuid().ToString(), ex.Message, Logger.ServerityLevel.ERROR);
                Logger.doLog(Guid.NewGuid().ToString(), ex.StackTrace, Logger.ServerityLevel.ERROR);
                outException = ex;
                return false;
            }
            finally
            {
                Searcher = null;
                Scope = null;
                //HostName = null;
                Query = null;
                QueryCol = null;
                inParams = null;
                imo = null;
                nvc = null;
                outParams = null;
                mbo = null;
                pde = null;
                qde = null;
            }
        }

        public static bool Unenlist(GML.BizTalk.OperationManager.MSBTSOperations.MSBTS_Orchestration oOrchestration, ref List<GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject> outputParams, ref Exception outException)
        {
            //set up a WMI query to acquire a list of orchestrations with the given Name and 
            //AssemblyName key values.  This should be a list of zero or one Orchestrations.
            //Create the WMI search object.
            ManagementObjectSearcher Searcher = new ManagementObjectSearcher();
            // create the scope node so we can set the WMI root node correctly.
            ManagementScope Scope = null;
            //string HostName = "";
            // Build a Query to enumerate the MSBTS_Orchestration instances with the
            // specified name and assembly name.
            SelectQuery Query = new SelectQuery();
            ManagementObjectCollection QueryCol = null;
            ManagementBaseObject inParams = null;
            System.Management.InvokeMethodOptions imo = null;
            ManagementNamedValueCollection nvc = null;
            ManagementBaseObject outParams = null;
            GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject mbo = null;
            PropertyDataCollection.PropertyDataEnumerator pde = null;
            QualifierDataCollection.QualifierDataEnumerator qde = null;
            try 
	            {	        
                                Searcher = new ManagementObjectSearcher();

                                Scope = new ManagementScope("root\\MicrosoftBizTalkServer");
                                Searcher.Scope = Scope;

                                Query = new SelectQuery();
                                // Build a Query to enumerate the MSBTS_Orchestration instances with the
                                // specified name and assembly name.
                                Query.QueryString = "SELECT * FROM MSBTS_Orchestration WHERE Name = '" + oOrchestration.Properties.Name +
                                                                      "' AND AssemblyName = '" + oOrchestration.Properties.AssemblyName +
                                                                     "'  AND AssemblyVersion  = '" + oOrchestration.Properties.AssemblyVersion +
                                                                     "'  AND AssemblyCulture  = '" + oOrchestration.Properties.AssemblyCulture +
                                                                     "'  AND AssemblyPublicKeyToken   = '" + oOrchestration.Properties.AssemblyPublicKeyToken + "' ";

                                // Set the query for the searcher.
                                Searcher.Query = Query;
                                QueryCol = Searcher.Get();

                                // Use a bool to tell if we enter the for loop
                                // below because Count property is not supported
                                bool OrchestrationFound = false;

                                foreach (ManagementObject Inst in QueryCol)
                                {
                                    // There is at least one Orchestration
                                    OrchestrationFound = true;
                                    int OrchestrationStatus = Convert.ToInt32(Inst.GetPropertyValue("OrchestrationStatus"));
                                    System.Diagnostics.Debug.WriteLine("The Orchestration status is: " + OrchestrationStatus + ".");
                                    Logger.doLog(Guid.NewGuid().ToString(), "The Orchestration status is: " + OrchestrationStatus + ".", Logger.ServerityLevel.INFO);
                                    if (OrchestrationStatus != Convert.ToInt32(GML.BizTalk.OperationManager.Library.OrchestrationStatus.Started)
                                        && OrchestrationStatus != Convert.ToInt32(GML.BizTalk.OperationManager.Library.OrchestrationStatus.Stopped))
                                    {
                                        return true;
                                    }

                                    inParams = Inst.GetMethodParameters("Unenlist");

                                    //AutoTerminateOrchestrationInstanceFlag  [in] An Integer specifying whether instances of this orchestration type should be automatically terminated. Permissible values for this parameter are (1) "Do not terminate service instances of this orchestration," or (2) "Terminate all service instances of this orchestration." Note that the integer values must be used in code and script. The default value is 1.
                                    if (oOrchestration.InputParams != null && oOrchestration.InputParams.Length > 0)
                                    {
                                        foreach (GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject inputParam in oOrchestration.InputParams)
                                        {
                                            inParams[inputParam.Param] = inputParam.Value;
                                        }
                                    }

                                    imo = null;
                                    if (oOrchestration.InvokeMethodOptions != null)
                                    {
                                        nvc = new ManagementNamedValueCollection();
                                        GML.BizTalk.OperationManager.MSBTSOperations.ManagementNamedValueCollection[] nvcInputs = oOrchestration.InvokeMethodOptions;
                                        foreach (GML.BizTalk.OperationManager.MSBTSOperations.ManagementNamedValueCollection nvcInput in nvcInputs)
                                        {
                                            nvc.Add(nvcInput.Name, nvcInput.Value);
                                        }
                                        if (oOrchestration.TimeOut != null)
                                        {
                                            imo = new InvokeMethodOptions(nvc, new TimeSpan(oOrchestration.TimeOut.Day, oOrchestration.TimeOut.Hour, oOrchestration.TimeOut.Minute, oOrchestration.TimeOut.Second, oOrchestration.TimeOut.Millisecond));
                                        }
                                        else
                                        {
                                            imo = new InvokeMethodOptions(nvc, new TimeSpan(0, 15, 0));
                                        }
                                    }

                                    //Execute the method
                                    outParams = Inst.InvokeMethod("Unenlist", inParams, imo);
                                    System.Diagnostics.Debug.WriteLine("The Orchestration [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "] was successfully Unenlisted.");
                                    Logger.doLog(Guid.NewGuid().ToString(), "The Orchestration [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "] was successfully Unenlisted.", Logger.ServerityLevel.INFO);
                                    mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                                    if (outputParams == null) outputParams = new List<GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject>();
                                    pde = outParams.Properties.GetEnumerator();
                                    while (pde.MoveNext())
                                    {
                                        try
                                        {
                                            mbo.Param = pde.Current.ToString();
                                            mbo.Value = outParams.GetPropertyValue(mbo.Param).ToString();

                                            outputParams.Add(mbo);
                                        }
                                        catch (Exception)
                                        {
                                        }
                                        mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                                    }
                                    pde = outParams.SystemProperties.GetEnumerator();
                                    while (pde.MoveNext())
                                    {
                                        try
                                        {
                                            mbo.Param = pde.Current.ToString();
                                            mbo.Value = outParams.GetPropertyValue(mbo.Param).ToString();

                                            outputParams.Add(mbo);

                                        }
                                        catch (Exception e)
                                        {
                                            Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                                            Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);
                                        }
                                        mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                                    }

                                    qde = outParams.Qualifiers.GetEnumerator();
                                    while (qde.MoveNext())
                                    {
                                        try
                                        {
                                            mbo.Param = qde.Current.ToString();
                                            mbo.Value = outParams.GetQualifierValue(mbo.Param).ToString();

                                            outputParams.Add(mbo);

                                        }
                                        catch (Exception e)
                                        {
                                            Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                                            Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);

                                        }
                                        mbo = new GML.BizTalk.OperationManager.MSBTSOperations.ManagementBaseObject();
                                    }
                                }

                                if (!OrchestrationFound)
                                {
                                    System.Diagnostics.Debug.WriteLine("No Orchestration found  [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "].");
                                    Logger.doLog(Guid.NewGuid().ToString(), "No Orchestration found  [" + oOrchestration.Properties.Name + " " + oOrchestration.Properties.AssemblyName + ", Version=" + oOrchestration.Properties.AssemblyVersion + ", Culture=" + oOrchestration.Properties.AssemblyCulture + ", PublicKeyToken=" + oOrchestration.Properties.AssemblyPublicKeyToken + "].", Logger.ServerityLevel.INFO);
                                }
                                return true;
	            }
	            catch (Exception ex)
	            {
                    System.Diagnostics.Debug.WriteLine("An exception occurred " + ex.Message);
                    System.Diagnostics.Debug.WriteLine(ex.StackTrace);
                    Logger.doLog(Guid.NewGuid().ToString(), ex.Message, Logger.ServerityLevel.ERROR);
                    Logger.doLog(Guid.NewGuid().ToString(), ex.StackTrace, Logger.ServerityLevel.ERROR);
                    outException = ex;
                    return false;
	            }
            finally
            {
                Searcher = null;
                Scope = null;
                //HostName = null;
                Query = null;
                QueryCol = null;
                inParams = null;
                imo = null;
                nvc = null;
                outParams = null;
                mbo = null;
                pde = null;
                qde = null;
            }
        }
    }
}
